home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / vbccm68ksrc.lha / vbcc / vlink / t_elf64.c < prev    next >
C/C++ Source or Header  |  1999-03-07  |  47KB  |  1,473 lines

  1. /* $VER: vlink t_elf64.c V0.6a (19.12.98)
  2.  *
  3.  * This file is part of vlink, a portable linker for multiple
  4.  * object formats.
  5.  * Copyright (c) 1997-99  Frank Wille
  6.  *
  7.  * vlink is freeware and part of the portable and retargetable ANSI C
  8.  * compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
  9.  * vlink may be freely redistributed as long as no modifications are
  10.  * made and nothing is charged for it. Non-commercial usage is allowed
  11.  * without any restrictions.
  12.  * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
  13.  * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
  14.  *
  15.  *
  16.  * v0.6a (19.12.98) phx
  17.  *       Support for little endian object file formats.
  18.  *       ** t_elf64.c still doesn't work - don't activate it! **
  19.  * v0.6  (24.10.98) phx
  20.  *       .sdata/.sbss and .sdata2/.sbss2 will always be combined.
  21.  *       Each target defines their own base register section offsets.
  22.  *       Linking with shared objects is possible. Creating them is
  23.  *       a another story...
  24.  *       ** t_elf64.c still doesn't work - don't activate it! **
  25.  * v0.5d (22.08.98) phx
  26.  *       Faster memory allocation can be activated by #define FASTALLOC.
  27.  *       ** t_elf64.c still doesn't work - don't activate it! **
  28.  * v0.5  (27.06.98) phx
  29.  *       Target-specific linker symbol support: elf64_lnksym(),
  30.  *       elf64_setlnksym().
  31.  *       ** t_elf64.c still doesn't work - don't activate it! **
  32.  * v0.4  (05.06.98) phx
  33.  *       New FFF targetlink(). Currently no meaning for ELF.
  34.  *       ** t_elf64.c still doesn't work - don't activate it! **
  35.  * v0.0  (25.04.98) phx
  36.  *       File created.
  37.  */
  38.  
  39.  
  40. #if defined(ELF64_ALPHA)
  41. #define T_ELF64_C
  42. #include "vlink.h"
  43. #include "elf64.h"
  44. #if defined(ELF64_ALPHA)
  45. #include "rel_elfalpha.h"
  46. #endif
  47.  
  48. #define ELF_VER 1
  49.  
  50.  
  51. #ifdef ELF64_ALPHA
  52. static int alpha64_identify(char*,uint8 *,unsigned long);
  53. static void alpha64_readconv(struct GlobalVars *,struct LinkFile *);
  54. static void alpha64_readELF(struct GlobalVars *,struct LinkFile *,uint8 *);
  55. static unsigned long alpha64_secbase(struct GlobalVars *,char *);
  56. static uint8 alpha64_cmpsecflags(uint8,uint8);
  57. static struct Section *alpha64_bssdefault(struct ObjectUnit *);
  58. static int alpha64_targetlink(struct GlobalVars *,struct LinkedSection *,
  59.                               struct Section *);
  60. static struct Symbol *alpha64_lnksym(struct GlobalVars *,struct Section *,
  61.                                      struct XReference *);
  62. static void alpha64_setlnksym(struct GlobalVars *,struct Symbol *,
  63.                               struct XReference *);
  64. static void alpha64_relocs(struct GlobalVars *,uint8 *,struct ObjectUnit *,
  65.                            struct Elf64_Shdr *);
  66. static void alpha64_writeobject(struct GlobalVars *,FILE *);
  67. static void alpha64_writeshared(struct GlobalVars *,FILE *);
  68. static void alpha64_writeexec(struct GlobalVars *,FILE *);
  69. static uint8 alpha64_getrel(uint8,char *,uint32);
  70.  
  71. struct FFFuncs fff_elf64alpha = {
  72.   "elf64alpha",
  73.   alpha64_identify,
  74.   alpha64_readconv,
  75.   alpha64_secbase,
  76.   alpha64_cmpsecflags,
  77.   alpha64_bssdefault,
  78.   alpha64_targetlink,
  79.   alpha64_lnksym,
  80.   alpha64_setlnksym,
  81.   alpha64_writeobject,
  82.   alpha64_writeshared,
  83.   alpha64_writeexec,
  84.   0x7ff0,  /*@@@ I have no information */
  85.   NULL,
  86.   0 /* little endian */
  87. };
  88. #endif
  89.  
  90. /* small data sections */
  91. static char *sdata = ".sdata";
  92. static char *sbss = ".sbss";
  93. static char *sdata2 = ".sdata2";
  94. static char *sbss2 = ".sbss2";
  95.  
  96.  
  97. static int elf64le_identify(struct FFFuncs *,char *,struct Elf64_Ehdr *,
  98.                             unsigned long,unsigned char,unsigned char,
  99.                             uint16,uint32);
  100. static void elf64le_check_ar_type(struct FFFuncs *,char *,
  101.                                   struct Elf64_Ehdr *,unsigned char,
  102.                                   unsigned char,uint32,uint16,uint16,uint16);
  103. static char *elf64le_shstrtab(struct LinkFile *,struct Elf64_Ehdr *);
  104. static char *elf64le_strtab(struct LinkFile *,struct Elf64_Ehdr *,int);
  105. static struct Elf64_Sym *elf64le_symtab(struct LinkFile *,
  106.                                         struct Elf64_Ehdr *,int);
  107. static struct Elf64_Shdr *elf64le_shdr(struct LinkFile *lf,
  108.                                        struct Elf64_Ehdr *,uint16);
  109. static void elf64le_section(uint8 *,struct ObjectUnit *,
  110.                             struct Elf64_Shdr *,int);
  111. static void elf64le_symbols(struct GlobalVars *,uint8 *,struct ObjectUnit *,
  112.                             struct Elf64_Shdr *);
  113. static void elf64le_reloc(struct GlobalVars *,struct Elf64_Ehdr *,
  114.                           struct Section *,uint32,struct Elf64_Rela *,
  115.                           bool,uint8);
  116. static struct Section *elf64le_bssdefault(struct ObjectUnit *);
  117. static int elf64_targetlink(struct GlobalVars *,struct LinkedSection *,
  118.                             struct Section *);
  119. static struct Symbol *elf64_lnksym(struct GlobalVars *,struct Section *,
  120.                                    struct XReference *);
  121. static void elf64_setlnksym(struct GlobalVars *,struct Symbol *,
  122.                             struct XReference *);
  123. static void elf64le_header(FILE *,uint16,uint16,uint32,uint32,uint32,
  124.                            uint32,uint16,uint16,uint16);
  125. static void elf64le_writeshdrs(FILE *,uint32,uint32);
  126. static void elf64le_stdsymtab(struct GlobalVars *,uint8,uint8);
  127. static void elf64le_addsymlist(struct GlobalVars *,struct SymTabList *,
  128.                                uint8,uint8);
  129. static void elf64le_makeshdrs(struct GlobalVars *);
  130. static void elf64le_addrelocs(struct GlobalVars *,
  131.                               uint8 (*)(uint8,char *,uint32));
  132. static void elf64le_makeshstrtab(void);
  133. static void elf64le_makestrtab(void);
  134. static void elf64le_makesymtab(uint32);
  135. static struct ShdrNode *elf64le_addshdr(uint32,uint32,uint32,uint32,uint32,
  136.                                         uint32,uint32,uint32,uint32,uint32);
  137. static uint32 elf64le_addsym(struct SymTabList *,char *,uint32,uint32,
  138.                              uint8,uint8,uint16);
  139. static uint32 elf64le_findsym(struct SymTabList *,char *,uint16);
  140. static void elf64le_addrela(uint32,int32,uint32,uint8);
  141.  
  142. static void elf64_initlists(void);
  143. static struct ShdrNode *elf64_newshdr(void);
  144. static uint32 elf64_addshdrstr(char *);
  145. static uint32 elf64_addstr(char *);
  146. static uint32 elf64_addstrlist(struct StrTabList *,char *);
  147. static uint8 elf64_getinfo(struct Symbol *);
  148. static uint8 elf64_getbind(struct Symbol *);
  149. static uint16 elf64_getshndx(struct Symbol *,uint8);
  150. static void elf64_writesections(struct GlobalVars *,FILE *);
  151. static void elf64_writestrtab(FILE *,struct StrTabList *);
  152. static void elf64_writesymtab(FILE *,struct SymTabList *);
  153. static void elf64_writerelocs(struct GlobalVars *,FILE *);
  154.  
  155.  
  156. static char ELFid[4] = {   /* identification for all ELF files */
  157.   0x7f,'E','L','F'
  158. };
  159.  
  160. static struct ar_info ai;  /* for scanning library archives */
  161. static char *shstrtab;     /* section header string table */
  162. static char *nullstr = "";
  163.  
  164. /* static data required for output file generation */
  165. static struct list shdrlist;
  166. static struct list phdrlist;
  167. static struct list relalist;
  168. static struct SymTabList symlist;
  169. static struct StrTabList shstrlist;
  170. static struct StrTabList stringlist;
  171. static uint32 shdrindex;
  172. static uint32 symtabidx,shstrtabidx,strtabidx; /* indexes of Shdr names */
  173. static uint32 elfoffset;    /* current ELF file offset */
  174. static int secsyms;         /* offset to find section symbols by shndx */
  175.  
  176.  
  177.  
  178. /*****************************************************************/
  179. /*                          Read ELF                             */
  180. /*****************************************************************/
  181.  
  182.  
  183. #ifdef ELF64_ALPHA
  184.  
  185. static int alpha64_identify(char *name,uint8 *p,unsigned long plen)
  186. /* identify ELF-Alpha-64Bit-LittleEndian */
  187. {
  188.   return (elf64le_identify(&fff_elf64alpha,name,(struct Elf64_Ehdr *)p,plen,
  189.                            ELFCLASS64,ELFDATA2LSB,EM_ALPHA,ELF_VER));
  190. }
  191.  
  192.  
  193. static void alpha64_readconv(struct GlobalVars *gv,struct LinkFile *lf)
  194. /* Read elf64alpha executable / object / shared obj. */
  195. {
  196.   if (lf->type == ID_LIBARCH) {
  197.     if (ar_init(&ai,(char *)lf->data,lf->length,lf->filename)) {
  198.       while (ar_extract(&ai)) {
  199.         lf->objname